import java.awt.event.*;
import java.awt.*;
import java.io.*;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileNameExtensionFilter;

import ausgabeUndDatenverwaltung.*;
import pruefungsPlanung.*;
import einlesenUndDatenverwaltung.*;

/**
 * Zentrale Steuerungslogikklasse. In dieser Klasse werden die Eingaben der
 * grafischen Oberflaeche ausgewertet und die entsprechenden
 * Methoden/Konstruktoren zum Einlesen von Dateien, der Pruefungsplanung und zur
 * Ausgabe aufgerufen.
 * 
 * @author (Kerstin Schulze)
 * @version (17.1.2014)
 */
public class SteuerungsController implements ActionListener, ChangeListener {
	// Attribute
	private VawiOrgaTool vot;
	private String file1;
	private String file2;
	private String file3;

	private String button1;
	private String button2;
	private String button3;
	private InputListenErzeuger ein = new InputListenErzeuger();
	private StudentenListe sl;
	private BuchungsListe bu;
	private KursListe kl;
	private String pfad;
	private PruefungsPlanung pp;
	private int gewaehltesTab;
	private String platzkartenliste;
	private String anwesenheitsliste;
	private String pruefungsplan;
	private String notenliste;
	private String zufriedenheitsmessung;

	/**
	 * Konstruktor zur Erzeugung der Objekte der Klasse SteuerungsController.
	 */
	public SteuerungsController(VawiOrgaTool vot) {
		this.vot = vot;
	}

	/**
	 * Verarbeiten der Listener von der grafischen Oberflaeche und
	 * Methodenaufrufe. Des Weiteren erzeugt die Methode gewuenschte Ausgaben
	 * auf der grafischen Oberflaeche.
	 * 
	 * @param: ActionEvent e (ActionEvent) Die Events der GUI
	 */
	public void actionPerformed(ActionEvent e) {

		// Verarbeiten der EventListener(Auswahl auf der grafischen Oberflaeche)
		Object obj = e.getSource();

		// Button 1: Einlesen Studentendatei und Ausgabe im Textarea
		if ((obj == vot.button1) || (obj == vot.oeffnen1)) {
			// JFileChooser-Objekt erstellen
			JFileChooser chooser = new JFileChooser();
			// Dialog zum Oeffnen von Dateien anzeigen
			int rueckgabeWert = chooser.showOpenDialog(null);

			// Abfrage, ob auf "Oeffnen" geklickt wurde
			if (rueckgabeWert == JFileChooser.APPROVE_OPTION) { // Dateipfad
				file1 = chooser.getSelectedFile().getPath();
				// Ausgabe der ausgewaehlten Datei
				System.out.println("Die zu oeffnende Datei ist: " + file1);
				// setzen des Wertes fuer den Button (button1= Studentendatei)
				button1 = "button1";

				// Erzeugen der Studentenliste
				sl = new StudentenListe();
				// Setzen der erzeugten Studentenliste
				ein.setStudentenListe(sl);

				// Einlesen der Dateien
				ein.ladeDatei(file1, button1);
				// zaehler, wieviele Elemente sind in Liste (Ist es eine
				// Studentendatei? Studentendatei=Zaehler 6)
				int zaehler = ein.getZaehler();

				// holen der Studentenliste
				sl = ein.getStudentenListe();

				if ((chooser.getSelectedFile().getName() != null)
						&& (zaehler == 6)) {
					// BufferedReader in = null;
					vot.textarea1.selectAll();
					vot.textarea1.replaceRange("",
							vot.textarea1.getSelectionStart(),
							vot.textarea1.getSelectionEnd());
					vot.textarea1
							.append("Eingelesen der Studentenliste erfolgreich. Folgende Daten wurden eingelesen:"
									+ "\n"+ "Anzahl der Studenten in der Liste: " +sl.anzStudenten() +"\n"+"\n");
					if (sl.anzStudenten() > 0) {
						// Schleife, die alle Objekte der Studentenliste
						// durchlaeuft
						for (int i = 0; i < sl.anzStudenten(); i++) {
							// Ausgeben des aktuellen Studentenobjekte, bzw. der
							// enthaltenen Werte
							Student stud = (Student) sl.getStudentAtIndex(i);
							int matrikelnummer = stud.getMatrikelnummer();
							String name = stud.getName();
							String vorname = stud.getVorname();
							String wohnort = stud.getWohnort();
							String uni = stud.getUniversitaet();
							boolean zeitminimierer = stud
									.getIstZeitminimierer();
							vot.textarea1.append("Student mit Matrikelnummer: "
									+ matrikelnummer + ",  Nachname: " + name
									+ ",  Vorname: " + vorname + ",  Wohnort: "
									+ wohnort + ",  Universitaet: " + uni
									+ ",  Ist Zeitminimierer: "
									+ zeitminimierer + "\n");
						}
					} else {
						// Erzeugen einer Fehlerausgabe in einem Fenster
						JOptionPane
								.showMessageDialog(
										null,
										"Die angegebene Liste enthaelt keine Objekte. Einlesen nicht erfolgreich.",
										"Hinweis",
										JOptionPane.INFORMATION_MESSAGE);
					}

				} else {
					JOptionPane.showMessageDialog(null,
							"Bitte lesen Sie eine Studentendatei ein!",
							"falsche Dateie(n)", JOptionPane.ERROR_MESSAGE);

				}
			}

		}

		// Button2: Einlesen Buchungsdatei und Ausgabe im Textarea
		if ((obj == vot.button2) || (obj == vot.oeffnen2)) {
			// JFileChooser-Objekt erstellen
			JFileChooser chooser = new JFileChooser();
			// Dialog zum Oeffnen von Dateien anzeigen
			int rueckgabeWert = chooser.showOpenDialog(null);

			/* Abfrage, ob auf "Oeffnen" geklickt wurde */
			if (rueckgabeWert == JFileChooser.APPROVE_OPTION) {
				// Dateipfad
				file2 = chooser.getSelectedFile().getPath();
				// Ausgabe der ausgewaehlten Datei
				System.out.println("Die zu oeffnende Datei ist: " + file2);
				// setzen des Wertes fuer den Button (button2= Buchungsdatei)
				button2 = "button2";

				// Erzeugen der Buchungsliste
				bu = new BuchungsListe();
				// Setzen der erzeugten Buchungsliste
				ein.setBuchungsListe(bu);

				// Einlesen der Dateien
				ein.ladeDatei(file2, button2);
				// zaehler, wieviele Elemente sind in Liste (Ist es eine
				// Buchungsdatei? Buchungsdatei=Zaehler 3)
				int zaehler = ein.getZaehler();

				// holen der Buchungsliste
				bu = ein.getBuchungsListe();

				// wurde Dateiname gewaehlt und ist zaehler=3 fuer Buchungsliste
				if ((chooser.getSelectedFile().getName() != null)
						&& (zaehler == 3)) {
					// Textarea selektieren
					vot.textarea2.selectAll();
					vot.textarea2.replaceRange("",
							vot.textarea2.getSelectionStart(),
							vot.textarea2.getSelectionEnd());
					vot.textarea2
							.append("Eingelesen der Buchungsliste erfolgreich. Folgende Daten wurden eingelesen:"
									+ "\n"+ "Anzahl der Buchungen: "+bu.anzBuchungen()+ "\n"+"\n");

					if (bu.anzBuchungen() > 0) {
						// Schleife, die alle Objekte der Buchungsliste
						// durchlaeuft
						for (int i = 0; i < bu.anzBuchungen(); i++) {
							// Ausgeben des aktuellen Buchungsojekte, bzw. der
							// enthaltenen Werte
							Buchung buch = (Buchung) bu.getBuchungAtIndex(i);
							int studentid = buch.getStudent();
							int kursid = buch.getKurs();
							int punkte = buch.getPunkte();

							vot.textarea2.append("Student mit Matrikelnummer: "
									+ studentid + ",  Kurs mit Kursid: "
									+ kursid + ",  erreichte Punkte: " + punkte
									+ "\n");
						}
					} else {
						// Erzeugen einer Fehlerausgabe in einem Fenster
						JOptionPane
								.showMessageDialog(
										null,
										"Die angegebene Liste enthaelt keine Objekte. Einlesen nicht erfolgreich.",
										"Hinweis",
										JOptionPane.INFORMATION_MESSAGE);
					}

				} else {
					JOptionPane.showMessageDialog(null,
							"Bitte lesen Sie eine Buchungsdatei ein!",
							"falsche Dateie(n)", JOptionPane.ERROR_MESSAGE);

				}
			}
		}
		// Button 3: Einlesen Kursdatei und Ausgabe im Textarea
		if ((obj == vot.button3) || (obj == vot.oeffnen3)) {
			// JFileChooser-Objekt erstellen
			JFileChooser chooser = new JFileChooser();
			// Dialog zum Oeffnen von Dateien anzeigen
			int rueckgabeWert = chooser.showOpenDialog(null);

			/* Abfrage, ob auf "Oeffnen" geklickt wurde */
			if (rueckgabeWert == JFileChooser.APPROVE_OPTION) {
				// Dateipfad
				file3 = chooser.getSelectedFile().getPath();
				// Ausgabe der ausgewaehlten Datei
				System.out.println("Die zu oeffnende Datei ist: " + file3);
				// setzen des Wertes fuer den Button (button3= Kursdatei)
				button3 = "button3";

				// Erzeugen der Kursliste
				kl = new KursListe();
				// Setzen der erzeugten Kursliste
				ein.setKursListe(kl);

				// Einlesen der Dateien
				ein.ladeDatei(file3, button3);
				// zaehler, wieviele Elemente sind in Liste (Ist es eine
				// Kursdatei? Kursdatei=Zaehler 4)
				int zaehler = ein.getZaehler();
				// System.out.println(zaehler);

				// holen der Kursliste
				kl = ein.getKursListe();

				// Ist Dateipfad gewaehlt und ist zaehler0 4 fuer Kursliste
				if ((chooser.getSelectedFile().getName() != null)
						&& (zaehler == 4)) {
					// Textarea selektieren
					vot.textarea3.selectAll();
					vot.textarea3.replaceRange("",
							vot.textarea3.getSelectionStart(),
							vot.textarea3.getSelectionEnd());

					vot.textarea3
							.append("Eingelesen der Kursliste erfolgreich. Folgende Daten wurden eingelesen:"
									+ "\n"+ "Anzahl der Kurse in der Kursliste: " +kl.anzKurse() +"\n"+"\n");

					if (kl.anzKurse() > 0) {
						// Schleife, die alle Objekte der Kursliste
						// durchlaeuft
						for (int i = 0; i < kl.anzKurse(); i++) {
							// Ausgeben des aktuellen Kursojekte, bzw. der
							// enthaltenen Werte
							Kurs kurs = (Kurs) kl.getKursAtId(i);
							int kursid = kurs.getKursid();
							String kurzname = kurs.getKurzname();
							String name = kurs.getName();
							boolean studlstg = kurs
									.isBewerteteStudienleistung();

							vot.textarea3.append("Kurs mit Kursid: " + kursid
									+ ",  Kurzname: " + kurzname
									+ ",  Kursname: " + name
									+ ",  Studienleistung: " + studlstg + "\n");
						}
					} else {
						// Erzeugen einer Fehlerausgabe in einem Fenster
						JOptionPane
								.showMessageDialog(
										null,
										"Die angegebene Liste enthaelt keine Objekte. Einlesen nicht erfolgreich.",
										"Hinweis",
										JOptionPane.INFORMATION_MESSAGE);
					}

				} else {
					JOptionPane.showMessageDialog(null,
							"Bitte lesen Sie eine Kursdatei ein!",
							"falsche Dateie(n)", JOptionPane.ERROR_MESSAGE);
				}
			}
		}
		// Starte Pruefungsplanung, dazu zunaechst Abfrage welche Dateien
		// fehlen, sonst kann nicht gestartet werden!
		if ((obj == vot.button4) || (obj == vot.sp)) {

			// fehlende Dateien Hinweis welche Dateien einzulesen sind
			if ((file1 == null) || (file2 == null) || (file3 == null)) {
				String fehlendedatei = "";

				if (file1 == null) {
					fehlendedatei = " Studentendatei";
				}
				if (file2 == null) {
					fehlendedatei = fehlendedatei + " Buchungsdatei";
				}
				if (file3 == null) {
					fehlendedatei = fehlendedatei + " Kursdatei";
				}
				// Ausgabe der fehlenden Dateien
				JOptionPane.showMessageDialog(null,
						"Bitte lesen Sie die drei Dateien ein. Fehlende Datei (n): "
								+ fehlendedatei, "fehlende Dateie(n)",
						JOptionPane.ERROR_MESSAGE);
			} else {
				// starte Pruefungsplanung
				pp = new PruefungsPlanung();
				pp.optimiere(bu, kl, sl);
				
				// starte Zufriedenheitsmessung
				PlatzKartenListe pkl = pp.getAl().getPlatzkartenliste();
				ZufriedenheitsMesser zm = new ZufriedenheitsMesser();
				zm.pruefeZufriedenheit(pkl);
				

				// Ausgabe auf GUI starten--------------------------------
				
				//Hole die Zufriedenheitsmessung fuer Ausgabe
				zufriedenheitsmessung = zm.toString();
			
				// Hole Platzkartenliste fuer Ausgabe
				platzkartenliste = pp.getAl().getPlatzkartenliste()
						.toString();
				// Hole Anwesenheitsliste fuer Ausgabe
				anwesenheitsliste = pp.getAl()
						.getAnwesenheitslistenprotagunduni().toString();	

				
				// Hole Pruefungsplan fuer Ausgabe
			    pruefungsplan=pp.getAl().getPruefungsplan().toString();
			    
			    //Hole Notenliste nach UNI fuer Ausgabe
			    NotenListe ne=pp.getAl().getNotenliste();
			    
			    notenliste=pp.getAl().getNotenliste().createNotenlisteNachUni(ne).toString();

				// Ausgabe wenn Platzkartenliste, als Ergebnis des Algoritmus
				// nicht leer war
				if (pkl.anzPlatzkarten() > 0) {
					// Selektiere Textarea auf Tab 7: Ausgabe platzkartenliste
					vot.textarea7.selectAll();
					vot.textarea7.replaceRange("",
							vot.textarea7.getSelectionStart(),
							vot.textarea7.getSelectionEnd());
					vot.textarea7
							.append("Pruefungsplanung erfolgreich. Folgende Daten wurden geplant:"
									+ "\n" + "\n" + platzkartenliste);

					// Selektiere Textarea auf Tab 6: Ausgabe anwesenheitsliste
					vot.textarea6.selectAll();
					vot.textarea6.replaceRange("",
							vot.textarea6.getSelectionStart(),
							vot.textarea6.getSelectionEnd());
					vot.textarea6
							.append("Pruefungsplanung erfolgreich. Folgende Daten wurden geplant:"
									+ "\n" + "\n" + anwesenheitsliste);

					// Selektiere Textarea auf Tab 4: ausgabe pruefungsplan
					vot.textarea4.selectAll();
					vot.textarea4.replaceRange("",
							vot.textarea4.getSelectionStart(),
							vot.textarea4.getSelectionEnd());
					vot.textarea4
							.append("Pruefungsplanung erfolgreich. Folgende Daten wurden geplant:"
									+ "\n" + "\n"+pruefungsplan);
					
					// Selektiere Textarea auf Tab 8: ausgabe zufriedenheitsmesser
					vot.textarea8.selectAll();
					vot.textarea8.replaceRange("",
							vot.textarea8.getSelectionStart(),
							vot.textarea8.getSelectionEnd());
					vot.textarea8
							.append("Pruefungsplanung erfolgreich. Zufriedenheit mit dem ermittelten Pruefungsplan:"
									+ "\n\n Zusammenfassung: \n Anzahl Studenten mit mind. einer Kursbuchung: " +zm.anzs  + "\n Davon Anzahl zufriedener Studenten: " +zm.anzz + "\n Davon Anzahl unzufriedener Studenten: "  +zm.anzu + "\n\n Zufriedenheit im Einzelnen: " +zufriedenheitsmessung);
					
					// Selektiere Textarea auf Tab 5: ausgabe notenliste
					vot.textarea5.selectAll();
					vot.textarea5.replaceRange("",
							vot.textarea5.getSelectionStart(),
							vot.textarea5.getSelectionEnd());
					vot.textarea5
							.append("Pruefungsplanung erfolgreich. Folgende Daten wurden geplant:"
									+ "\n" + "\n"+notenliste);

					// Umsetzen des Fokus auf den Tab Pruefungsterminplan
					vot.tabs.setSelectedIndex(3);
					vot.button4.setEnabled(false);
					vot.sp.setEnabled(false);
				} else {
					// Erzeugen einer Fehlerausgabe in einem Fenster
					JOptionPane
							.showMessageDialog(
									null,
									"Die angegebene Liste enthaelt keine Objekte. Pruefungsplanung nicht erfolgreich.",
									"Hinweis", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		}

		// Menueeintrag speichern
		if (obj == vot.speichern) {
			// Neuer FileChooser zum Speichern
			JFileChooser chooser = new JFileChooser();
			chooser.setDialogType(JFileChooser.SAVE_DIALOG);
			// Filter: nur bestimmte Dateitypen
			FileNameExtensionFilter plainFilter = new FileNameExtensionFilter(
					"Plaintext: txt, csv", "txt", "csv");
			chooser.removeChoosableFileFilter(chooser.getAcceptAllFileFilter());
			chooser.setFileFilter(plainFilter);
			chooser.setDialogTitle("Speichern unter...");
			chooser.setVisible(true);

			int result = chooser.showSaveDialog(null);

			if (result == JFileChooser.APPROVE_OPTION) {

				// Dateipfad aus Chooser
				pfad = chooser.getSelectedFile().toString();
				// ist ein Pfad angegeben, wenn nicht setzen; Default:txt Datei
				if((!pfad.toLowerCase().endsWith(".txt"))||(!pfad.toLowerCase().endsWith(".csv"))){
		             pfad = pfad + ".txt";
		           }
				
				File file = new File(pfad);
				if (plainFilter.accept(file)) {
					System.out.println(pfad + " kann gespeichert werden.");
					OutputErzeuger oe=new OutputErzeuger();

					// Schreiben der Files auf Dateisystem,
					// switch/Case welches Tab wurde gewaehlt-> je nachdem
					// Dateiausgabe
					switch (gewaehltesTab) {
					case 3:
						oe.dateiSchreiben(pfad, pruefungsplan);
						//System.out.println("Tab drei");
						break;
					case 4:
						 oe.dateiSchreiben(pfad, notenliste);
						//System.out.println("Tab vier");
						break;
					case 5:
						 oe.dateiSchreiben(pfad, anwesenheitsliste);
						//System.out.println("Tab fuenf");
						break;
					case 6:
						 oe.dateiSchreiben(pfad, platzkartenliste);
						//System.out.println("Tab sechs");
						break;
					case 7:
						 oe.dateiSchreiben(pfad, zufriedenheitsmessung);
						//System.out.println("Tab sechs");
						break;
					default:
						System.out
								.println("i liegt nicht zwischen drei und sechs");
					}

					// wenn Dateityp nicht laut Filter gewaehlt wurde
				} else {
					System.out.println(pfad + " ist der falsche Dateityp.");
				}
			}

		}
		// Menuepunkt ueber das Programm
		if (obj == vot.ueber) {
			// erzeugt ein Frame
			JFrame fenster = new JFrame("ueber das Programm");

			// Fenster schliessen, aber nicht Programm
			fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

			Container cp = fenster.getContentPane();

			cp.setLayout(null);
			// Text im Fenster
			JLabel label1 = new JLabel(
					"<html><body bgcolor=#FFFFFF width=600 height=450>"
							+ "<center><h3><font color=#848484>Hinweise zur Verwendung des Programms VawiOrgaTool</h3></center>"
							+ "<font color=black><div align=center>Im VawiOrgaTool koennen nur Dateien mit folgender Syntax sinnvoll verarbeitet werden:</div>"
							+ "<br><ul><li><b>Studentendatei:</b><br>Zur sinnvollen Verarbeitung von Studentendateien muessen im Format CSV vorliegen.<br>Die Dateien muessen in folgender Syntax vorliegen: Matrikelnummer (Zahl), Name (Zeichenkette), Vorname (Zeichenkette), Universitaet (Zeichenkette), Bundesland (Zeichenkette), Zeitminimierer (Zeichenkette).<br>Tennzeichen: Komma</li><br>"
							+ "<br><li><b>Buchungsdatei:</b><br>Zur sinnvollen Verarbeitung von Buchungsdateien muessen im Format CSV vorliegen.<br>Die Dateien muessen in folgender Syntax vorliegen: Matrikelnummer (Zahl), Kursnummer (Zahl), Punkte (Zahl).<br>Tennzeichen: Komma</li><br>"
							+ "<br><li><b>Kursdatei:</b><br>Zur sinnvollen Verarbeitung von Kursdateien muessen im Format CSV vorliegen.<br>Die Dateien m�ssen in folgender Syntax vorliegen: Kursnummer (Zahl), Kurzname (Zeichenkette), Langname (Zeichenkette), bewertete Studienleistung (Zeichenkette).<br>Tennzeichen: Komma</li><br>"
							+ "</ul></body></html>");
			label1.setBounds(0, 0, 600, 450);
			cp.add(label1);

			fenster.setLocation(100, 100);
			fenster.setSize(600, 450);
			// Fenster soll nicht vergroessert oder verkleinert werden
			fenster.setResizable(false);

			// Frame anzeigen
			fenster.setVisible(true);

		}

		// Menuepunkt schliessen, dann Programm beeenden
		if (e.getSource() == vot.beenden) {
			System.exit(0);
		}
	}

	/**
	 * ChangeListener Methode, informiert, wenn die Tabs auf der GUI gewechselt
	 * werden. Dann wird der Index gespeichert.
	 * 
	 * @param e
	 *            (Change Event) Das ausgeloeste Event
	 */
	public void stateChanged(ChangeEvent e) {
		JTabbedPane pane = (JTabbedPane) e.getSource();
		gewaehltesTab = pane.getSelectedIndex();
		// System.out.println("gewaehltes Tab: "+gewaehltesTab);
	}

}